package yxy.game.pm2.module.union;

import yxy.apple.util.UnicodeUtility;
import yxy.apple.util.concurrent.ThreadPoolManager;
import yxy.cherry.data.dfa.Sensitive;
import yxy.cherry.data.function.Function;
import yxy.cherry.data.string.GameString;
import yxy.cherry.game.base.message.MessageEmitterHandler;
import yxy.game.pm2.Result;
import yxy.game.pm2.bean.PlayerBean;
import yxy.game.pm2.bean.ServerBean;
import yxy.game.pm2.bean.area.AreaBean;
import yxy.game.pm2.bean.area.AreaGroupBean;
import yxy.game.pm2.bean.cluster.ClusterBean;
import yxy.game.pm2.bean.module.rank.RankEntry;
import yxy.game.pm2.bean.module.rank.openserviceactive.boosrushrank.OpenServiceBoosRushRank;
import yxy.game.pm2.message.UnionMessage;
import yxy.game.pm2.module.active.openservicerush.OpenServiceRushRecord;
import yxy.game.pm2.module.battle.BattleHandle;
import yxy.game.pm2.module.player.FunctionHandle;
import yxy.game.pm2.module.playtype.PlayTypeHandle;
import yxy.game.pm2.module.playtype.PlayTypeModule;
import yxy.game.pm2.module.union.boss.UnionBoss;
import yxy.game.pm2.module.union.player.UnionPlayer;
import yxy.game.pm2.module.union.rank.*;

import java.util.Collection;

public class UnionHandle {

	/*
	 * 盟主可在联盟成员中提拔3位副盟主，副盟主没有修改职位的权限。   盟主可以手动让位给其他人。  
	 * 盟主3天不在线，即自动让位给贡献度最高的副盟主，若该副盟主的状态也是离线3天或以上，则继续顺延，若无满足条件的副盟主，
	 * 则盟主让位给三日内有上过线的贡献最高的成员，同时盟主变为普通成员。   盟主和副盟主有踢人权限。
	 */

	/** 热门联盟列表 */
	public UnionMessage.UnionHotListResponse hotList(String playerCode) {
		PlayerBean playerBean = PlayerBean.get(playerCode);

		// 最活跃的前20个联盟随机10个
//		Collection<RankEntry> entries = new RankActiveUnion().randomEntry(playerCode, 0, 20, 10);
		Collection<RankEntry> entries = RankAreaActiveUnion.get(playerBean.getServerId()).randomEntry(playerCode, 0, 20, 10);

		UnionMessage.UnionHotListResponse.Builder builder = UnionMessage.UnionHotListResponse.newBuilder();

		for (RankEntry entry : entries) {

			String code = entry.getKey();
			UnionBean union = UnionBean.get(code);
			if (union == null) {
				continue;
			}
			builder.addUnions(packUnion(union));
		}
		builder.setResult(Result.Success.packResult());
		return builder.build();
	}

	public UnionMessage.Union packUnion(UnionBean union) {
		PlayerBean leader = PlayerBean.get(union.getLeader());
		UnionMessage.Union.Builder builder = UnionMessage.Union.newBuilder();
		builder.setCode(union.getCode());
		builder.setName(union.getName());
		builder.setAbbr(union.getAbbr());
		builder.setFlag(union.getFlag());
		builder.setLeaderName(leader.getName());
		builder.setLevel(union.getLevel());
		builder.setExp(union.getExp());
		builder.setNumber(union.members().size());
		builder.setSize(union.place());
		builder.setPower(union.getPower());

		if (union.getSlogan() != null) {
			builder.setSlogan(union.getSlogan());
		}

		UnionMessage.UnionJoin.Builder joinBuilder = UnionMessage.UnionJoin.newBuilder();
		joinBuilder.setCondition(UnionMessage.JoinCondition.forNumber(union.getJoinRule().getCondition().getNumber()));
		joinBuilder.setValue(union.getJoinRule().getValue());
		joinBuilder.setAudit(union.getJoinRule().isAudit());

		builder.setJoin(joinBuilder.build());

		return builder.build();
	}

	public UnionMessage.UnionMainResponse.Builder unionMain(UnionBean union, String playerCode) {
		UnionMessage.MemberType memberType = UnionMessage.MemberType.MEMBER;
		if (union.getLeader().equals(playerCode)) {
			memberType = UnionMessage.MemberType.LEADER;
		} else if (union.getViceList().contains(playerCode)) {
			memberType = UnionMessage.MemberType.VICE;
		}

		UnionMessage.UnionMainResponse.Builder response = UnionMessage.UnionMainResponse.newBuilder();
		UnionMessage.Union unionInfo = new UnionHandle().packUnion(union);
		response.setInfo(unionInfo);
		if (union.getNotice() != null) {
			response.setNotice(union.getNotice());
		}
		response.setType(memberType);
		response.setResult(Result.Success.packResult());
		return response;
	}

	public Result search(int serverId, String keyword, UnionMessage.UnionSearchResponse.Builder response) {
		ServerBean playerServerBean = ServerBean.get(serverId);

		Collection<String> codes = UnionName.search(keyword);
		for (String code : codes) {
			UnionBean union = UnionBean.get(code);
			ServerBean unionServerBean = ServerBean.get(union.getServerId());
			if (union == null || unionServerBean.getAreaId() != playerServerBean.getAreaId()) { //不同区
				continue;
			}
			response.addUnions(packUnion(union));
		}
		return Result.Success;
	}

	public Result addMember(UnionBean union, UnionPlayer unionPlayer) {
		if (union.members().size() >= union.place()) {
			return Result.UnionFull;// 联盟满员
		}

		union.getMemberList().add(unionPlayer.getPlayerCode());
		union.set();
		union.active();

		unionPlayer.setUnionCode(union.getCode());
		unionPlayer.reset();
		unionPlayer.set();

		String oppoCode = unionPlayer.getPlayerCode();
		PlayTypeModule playTypeModule = PlayTypeModule.get(oppoCode);
		PlayTypeHandle.saveUnion(oppoCode,playTypeModule);

		PlayTypeHandle.saveUnion(oppoCode, PlayTypeModule.get(oppoCode));
		new BattleHandle().powerUpdate(oppoCode);
		powerUpdate(union);

		// 联盟日志
		PlayerBean player = PlayerBean.get(unionPlayer.getPlayerCode());
		UnionLog.add(union.getCode(), GameString.联盟日志入盟(player.getName()).getText());

		// 联盟状态推送
		unionPlayerNotification(union, unionPlayer);
		//成员加入公会时同步开服冲榜的任务信息
		Runnable runnable = () -> {
			String playerCode = unionPlayer.getPlayerCode();
			boolean startActivity = OpenServiceBoosRushRank.isStartActivity(playerCode,1004);
			if(startActivity){
				UnionBoss boss = UnionBoss.get(union);
				OpenServiceRushRecord.recordPersonalBoosTask(playerCode, boss.getDataId() - 1);
			}
		};
		ThreadPoolManager.getInstance().execute(runnable);

		return Result.Success;
	}

	public Result checkName(String name, String abbr, String oriName) {
		if (name == null || name.length() <= 0 || abbr == null || abbr.length() <= 0) {
			return Result.UnionNameNotStandard;// 名字不太合适
		}
		// 长度检查
		if (name.length() > 6 || abbr.length() > 2) {
			return Result.UnionNameLengthTooLong;// 名字太长了
		}
		// 检查重名
		if (oriName == null || !name.equals(oriName)) {
			if (UnionName.getInstance().exist(name)) {
				return Result.UnionNameUsed;// 名字已经被用了
			}
		}
		if (!UnicodeUtility.checkUnicode(name, UnicodeUtility.UnicodeSet_Name) || !UnicodeUtility.checkUnicode(abbr, UnicodeUtility.UnicodeSet_Name)) {
			return Result.UnionNameNotStandard;// 名字不太合适
		}
		// 敏感词检查
		if (Sensitive.isSensitive(name) || Sensitive.isSensitive(abbr)) {
			return Result.UnionNameNotStandard;// 名字不太合适
		}
		return Result.Success;
	}

	public Result checkSlogan(String slogan) {
		if (slogan == null || slogan.length() <= 0) {
			return Result.ParamError;
		}
		slogan = UnicodeUtility.trimUnicode(slogan, UnicodeUtility.UnicodeSet_Chat);
		// 敏感词检查
		if (Sensitive.isSensitive(slogan)) {
			return Result.UnionSloganNotStandard;// 用词不合规
		}
		return Result.Success;
	}

	public Result checkNotice(String notice) {
		if (notice == null || notice.length() <= 0) {
			return Result.ParamError;
		}
		notice = UnicodeUtility.trimUnicode(notice, UnicodeUtility.UnicodeSet_Chat);
		// 敏感词检查
		if (Sensitive.isSensitive(notice)) {
			return Result.UnionNoticeNotStandard;// 用词不合规
		}
		return Result.Success;
	}

	public boolean checkArea(UnionBean union, PlayerBean playerBean) {
		try {
			ServerBean serverUnion = ServerBean.get(union.getServerId());
			ServerBean serverPlayer = ServerBean.get(playerBean.getServerId());
			return serverUnion.getAreaId() == serverPlayer.getAreaId();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	// entry==========================================================================

	static public class UnionPlayerEntry {
		private String playerCode;
		private UnionPlayer unionPlayer;
		private UnionBean unionBean;

		public UnionPlayerEntry(String playerCode) {
			this.playerCode = playerCode;
		}

		public String getPlayerCode() {
			return playerCode;
		}

		public UnionPlayer getUnionPlayer() {
			return unionPlayer;
		}

		public void setUnionPlayerModule(UnionPlayer unionPlayerModule) {
			this.unionPlayer = unionPlayerModule;
		}

		public UnionBean getUnionBean() {
			return unionBean;
		}

		public void setUnionBean(UnionBean unionBean) {
			this.unionBean = unionBean;
		}

		public UnionBean reloadUnionBean() {
			if (unionBean == null) {
				return null;
			}
			return unionBean = UnionBean.get(unionBean.getCode());
		}

		public UnionPlayer reloadUnionPlayer() {
			if (unionPlayer == null) {
				return null;
			}
			return unionPlayer = UnionPlayer.get(playerCode);
		}

	}

	/** 检查玩家是否有联盟 */
	public Result checkPlayerUnion(UnionPlayerEntry entry) {
		Result result = checkPlayerLevel(entry.getPlayerCode());
		if (!result.equals(Result.Success)) {
			return result;
		}
		UnionPlayer unionPlayer = UnionPlayer.get(entry.getPlayerCode());
		if (unionPlayer == null) {
			return Result.ModuleNotOpen;// 模块没开
		}
		entry.setUnionPlayerModule(unionPlayer);
		UnionBean union = UnionBean.get(unionPlayer.getUnionCode());
		if (union == null) {
			return Result.UnionOut;// 没有联盟
		}
		if (!union.members().contains(unionPlayer.getPlayerCode())) {
			unionPlayer.setUnionCode(null);
			unionPlayer.set();
			return Result.UnionOut;// 不属于这个联盟
		}
		entry.setUnionBean(union);
		return Result.UnionIn;
	}

	/** 检查玩家等级是否可以进入联盟 */
	public Result checkPlayerLevel(String playerCode) {
		PlayerBean playerBean = PlayerBean.get(playerCode);
		if (playerBean == null) {
			return Result.DataError;
		}
		if (!new FunctionHandle().check(Function.联盟, playerBean)) {
			return Result.ModuleNotOpen;
		}

		return Result.Success;
	}

	/** 检查是否盟主 */
	public Result checkPlayerUnionLeader(UnionPlayerEntry entry) {
		Result result = checkPlayerUnion(entry);
		if (!result.equals(Result.UnionIn)) {
			return result;
		}
		UnionBean union = entry.getUnionBean();
		if (union.getLeader().equals(entry.getPlayerCode())) {
			return Result.UnionLeader;
		}
		return Result.UnionNotLeader;
	}

	/** 检查是否管理员 */
	public Result checkPlayerUnionManager(UnionPlayerEntry entry) {
		Result result = checkPlayerUnionLeader(entry);
		if (result.equals(Result.UnionLeader)) {
			return Result.UnionManager;
		}
		UnionBean union = entry.getUnionBean();
		if (union.getViceList().contains(entry.getPlayerCode())) {
			return Result.UnionManager;
		}
		return Result.UnionNotManager;
	}

	// update==========================================================================

	public void powerUpdate(UnionBean union) {
		ServerBean serverBean = ServerBean.get(union.getServerId());
		AreaBean areaBean = AreaBean.get(serverBean.getAreaId());
		AreaGroupBean areaGroupBean = AreaGroupBean.get(areaBean.getGroupId());
		ClusterBean clusterBean = ClusterBean.get(areaBean.getClusterId());

		long power = union.power();
		new RankPowerUnion(clusterBean.getClusterId()).put(union.getCode(), power);
		RankAreaPowerUnion.get(union.getServerId()).put(union.getCode(), power);
		RankAreaGroupPowerUnion.get(areaGroupBean.getGroupId()).put(union.getCode(), power);
	}

	public void levelUpdate(UnionBean union) {
		ServerBean serverBean = ServerBean.get(union.getServerId());
		AreaBean areaBean = AreaBean.get(serverBean.getAreaId());
		AreaGroupBean areaGroupBean = AreaGroupBean.get(areaBean.getGroupId());
		ClusterBean clusterBean = ClusterBean.get(areaBean.getClusterId());

		new RankLevelUnion(clusterBean.getClusterId()).put(union.getCode(), union.getLevel());
		RankAreaLevelUnion.get(union.getServerId()).put(union.getCode(), union.getLevel());
		RankAreaGroupLevelUnion.get(areaGroupBean.getGroupId()).put(union.getCode(), union.getLevel());
	}

	/** 联盟日志 */
	public void sendLogInfo(UnionBean union, int type, String info) {

	}

	public void unionPlayerNotification(String playerCode) {
		UnionMessage.UnionPlayerNotification.Builder builder = UnionMessage.UnionPlayerNotification.newBuilder();

		UnionPlayerEntry entry = new UnionPlayerEntry(playerCode);
		Result result = new UnionHandle().checkPlayerUnion(entry);
		if (!result.equals(Result.UnionIn)) {
			builder.setCode("");
			MessageEmitterHandler.getInstance().send(playerCode, builder.build());
			return;
		}
		UnionBean union = entry.getUnionBean();

		builder.setCode(union.getCode());
		builder.setName(union.getName());
		MessageEmitterHandler.getInstance().send(playerCode, builder.build());
	}

	private void unionPlayerNotification(UnionBean union, UnionPlayer unionPlayer) {
		UnionMessage.UnionPlayerNotification.Builder builder = UnionMessage.UnionPlayerNotification.newBuilder();
		builder.setCode(union.getCode());
		builder.setName(union.getName());
		MessageEmitterHandler.getInstance().send(unionPlayer.getPlayerCode(), builder.build());
	}

}
